# -*- coding: UTF-8 -*-
# @Create   : 2021/10/8 14:41
# @Author   : yh
# @Remark   : IP设备Model层
import logging
import time
from urllib.parse import unquote
from typing import Union

from mxsoftpy import Model
from pydantic import constr, validator

from model.public.base import MxBaseModel, MxUpdateBaseModel
from utils.parser.fields import check_ipv4, check_mac
from index import _


class IPModel(MxBaseModel):
    """
    IP设备模型
    """
    ip: str                                                                      # ip地址
    mac: str = ''                                                                # mac地址
    plan_state: int                                                              # 规划状态 （0 已分配、1 未分配、2 保留）
    device_name: constr(max_length=50) = ''                                      # 设备名称
    principal: constr(max_length=50) = ''                                        # 负责人
    contact: str = ''                                                            # 联系方式
    location: constr(max_length=200) = ''                                        # 位置
    desc: constr(max_length=200) = ''                                            # 备注

    # 以下字段为c++方面定义
    active: int = 1
    deviceid: str = ''                                                           # 所属网络设备code（从哪个网络的路由表中发现的此ip）
    devicelabel: str = ''                                                        # 所属网络设备名称
    dnsname: str = ''
    if_: int = 0
    iflabel: str = ''
    isOld: int = 0                                                               # 是否信任此ip
    lIp: int = -1062731263                                                       # ip转换后的类型
    os: str = 0                                                                  # 设备操作系统
    time: str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))  # 添加时间

    # 校验ip是否符合ipv4格式
    _check_ip = validator('ip', allow_reuse=True)(check_ipv4)

    # 校验mac是否符合规则
    @validator('mac')
    def check_mac(cls, value):
        try:
            mac = unquote(value)
        except TypeError:
            logging.error('实例化IP模型时，发现无法进行url解码的mac地址：%s' % value)
            raise AssertionError(_('mac地址校验失败：%s') % value)
        return check_mac(mac) if mac else mac


class IPRetrieveModel(MxBaseModel):
    """
    IP设备展示模型
    """
    ip: str                                                                      # ip地址
    mac: str = ''                                                                # mac地址
    plan_state: int = 0                                                          # 规划状态 （0 已分配、1 未分配、2 保留）
    device_name: constr(max_length=50) = ''                                      # 设备名称
    principal: constr(max_length=50) = ''                                        # 负责人
    contact: str = ''                                                            # 联系方式
    location: constr(max_length=200) = ''                                        # 位置
    desc: constr(max_length=200) = ''                                            # 备注

    # 以下字段为c++方面定义
    active: int = 1
    deviceid: str = ''                                                           # 所属网络设备code（从哪个网络的路由表中发现的此ip）
    devicelabel: str = ''                                                        # 所属网络设备名称
    dnsname: str = ''
    if_: int = 0
    iflabel: str = ''
    isOld: int = 0                                                               # 是否信任此ip
    lIp: int = -1062731263                                                       # ip转换后的数据
    os: str = ''                                                                 # 设备操作系统
    time: str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))  # 添加时间


class IPUpdateModel(MxUpdateBaseModel):
    """
    IP设备更新模型
    """
    mac: str = ''                                          # mac地址
    plan_state: int                                        # 规划状态 （0 已分配、1 未分配、2 保留）
    device_name: constr(max_length=50) = ''                # 设备名称
    principal: constr(max_length=50) = ''                  # 负责人
    contact: str = ''                                      # 联系方式
    location: constr(max_length=200) = ''                  # 位置
    desc: constr(max_length=200) = ''                      # 备注

    # 解码并校验mac是否符合规则（为了防止空格识别错误，前端会将mac地址编码，因此需要解码再使用）
    @validator('mac')
    def check_mac(cls, value):
        try:
            mac = unquote(value)
        except TypeError:
            logging.error('实例化IP模型时，发现无法进行url解码的mac地址：%s' % value)
            raise AssertionError(_('mac地址校验失败：%s') % value)
        return check_mac(mac) if mac else mac


class IPSelectModel(Model):
    """
    IP设备查询参数模型
    """
    ip: str = ''                            # ip地址
    mac: str = ''                           # mac地址
    state: Union[int, str, None] = ''       # 状态 （0 未使用、1 已使用、2 30天内使用、3 30天前使用）
    plan_state: Union[int, str, None] = ''  # 规划状态 （0 已分配、1 未分配、2 保留）

    # 解码mac（为了防止空格识别错误，前端会将mac地址编码，因此需要解码再使用）
    @validator('mac')
    def check_mac(cls, value):
        try:
            mac = unquote(value)
        except TypeError:
            logging.error('实例化IP模型时，发现无法进行url解码的mac地址：%s' % value)
            raise AssertionError(_('mac地址校验失败：%s') % value)
        return mac
